package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class MovementManager {

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private MovementService movementService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private MQMovementManager mqMovementManager;

    // 发布动态
    public void saveMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.将图片上传到阿里云
        // 2-1 声明存储图片地址集合
        List<String> medias = new ArrayList<>();
        // 2-2 遍历文件对象
        if (ArrayUtil.isNotEmpty(imageContent)) {
            for (MultipartFile multipartFile : imageContent) {
                // 2-3 上传
                String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                // 2-4 存储图片到集合
                medias.add(url);
            }
        }
        // 3.封装movement实体
        movement.setId(ObjectId.get()); // 设置动态id（后期要用这个id）
        movement.setUserId(userId); // 发布人id
        movement.setMedias(medias); // 动态图片
        movement.setState(0);
        movement.setCreated(System.currentTimeMillis()); // 发布时间
        movement.setSeeType(1); // v1.0所有人都可看
        // 4.调用rpc发布动态
        movementService.saveMovement(movement);


        //---------------
        // 将动态id发送到mq （动态审核）
        rabbitTemplate.convertAndSend("tanhua.movement.log", movement.getId().toHexString());
        //---------------
        // 动态推荐
        mqMovementManager.sendMovement(userId, movement.getId(), MQMovementManager.MOVEMENT_PUBLISH);
        //----------------
    }

    @DubboReference
    private UserInfoService userInfoService;

    // 查看我的动态
    public ResponseEntity findMyMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        // 1.rpc查询动态分页
        PageBeanVo pageBeanVo = movementService.findMyMovementByPage(userId, pageNum, pageSize);
        // 2.封装movementVo
        // 2-1 声明voList
        List<MovementVo> voList = new ArrayList<>();
        // 2-2 获取动态列表
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 2-3 遍历
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 封装 vo
                MovementVo vo = new MovementVo();
                // 先userInfo
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                vo.setUserInfo(userInfo);
                // 后movement
                vo.setMovement(movement);

                // 判断是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }

                // 添加voList
                voList.add(vo);
            }
        }
        // 3.将voList设置到分页对象
        pageBeanVo.setItems(voList);

        // 4.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 查看好友动态
    public ResponseEntity findFriendMovementByPage(Integer pageNum, Integer pageSize) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc查询好友动态分页
        PageBeanVo pageBeanVo = movementService.findFriendMovementByPage(userId, pageNum, pageSize);
        // 3.封装movementVo
        // 3-1 声明voList
        List<MovementVo> voList = new ArrayList<>();
        // 3-2 获取movementList
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 3-3 遍历
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo
                MovementVo vo = new MovementVo();
                // 先 userInfo
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                vo.setUserInfo(userInfo);
                // 后 movement
                vo.setMovement(movement);

                // 判断是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }

                // 添加到 voList
                voList.add(vo);
            }
        }
        // 4.将voList设置到分页对象
        pageBeanVo.setItems(voList);

        // 5.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 查看推荐动态
    public ResponseEntity findRecommendMovementByPage(Integer pageNum, Integer pageSize) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.查看推荐动态详情分页
        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(userId, pageNum, pageSize);
        // 3.封装movementVo
        // 3-1 声明voList
        List<MovementVo> voList = new ArrayList<>();
        // 3-2 获取movementList
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 3-3 遍历
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo
                MovementVo vo = new MovementVo();
                // 先userInfo
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                vo.setUserInfo(userInfo);
                // 后movement
                vo.setMovement(movement);
                // 判断是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }
                // 判断是否喜欢
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movement.getId().toHexString()))) {
                    vo.setHasLoved(1);
                }

                // 添加voList
                voList.add(vo);
            }
        }
        // 4.将voList设置到分页对象
        pageBeanVo.setItems(voList);
        // 5.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    @DubboReference
    private CommentService commentService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // 点赞
    public ResponseEntity movementLike(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());// 点赞时间
        comment.setPublishId(movement.getId());// 动态id
        comment.setCommentType(1); // 点赞类型
        comment.setUserId(userId);// 操作人id
        comment.setPublishUserId(movement.getUserId());// 动态发布人id
        // 4.调用rpc保存
        Integer likeCount = commentService.saveComment(comment);
        // 5.存储redis点赞标记：    movement_like:{userId}_{publishId} = 1
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, publishId), "1");
        // 6.返回点赞数量
        return ResponseEntity.ok(likeCount);
    }

    // 取消点赞
    public ResponseEntity movementDisLike(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc删除
        Integer likeCount = commentService.removeComment(userId, new ObjectId(publishId), 1);
        // 3.删除redis点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, publishId));
        // 4.返回点赞数量
        return ResponseEntity.ok(likeCount);
    }

    // 喜欢
    public ResponseEntity movementLove(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.根据publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 3.封层comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());// 点赞时间
        comment.setPublishId(movement.getId());// 动态id
        comment.setCommentType(3); // 喜欢类型
        comment.setUserId(userId);// 操作人id
        comment.setPublishUserId(movement.getUserId());// 动态发布人id
        // 4.调用rpc保存
        Integer loveCount = commentService.saveComment(comment);
        // 5.redis存储喜欢标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, publishId), "1");
        // 6.返回喜欢数量
        return ResponseEntity.ok(loveCount);

    }

    // 取消喜欢
    public ResponseEntity movementUnLove(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc删除
        Integer loveCount = commentService.removeComment(userId, new ObjectId(publishId), 3);
        // 3.redis删除喜欢标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, publishId));
        // 4.返回喜欢数量
        return ResponseEntity.ok(loveCount);
    }

    // 单条动态（详情）
    public ResponseEntity findMovementVoById(String publishId) {
        // 1.查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 2.封装vo
        MovementVo vo = new MovementVo();
        // 先userInfo
        UserInfo userInfo = userInfoService.findById(movement.getUserId());
        vo.setUserInfo(userInfo);
        // 后movement
        vo.setMovement(movement);
        // 3.返回vo
        return ResponseEntity.ok(vo);
    }

    // 查看评论分页
    public ResponseEntity findCommentVoByPage(String publishId, Integer pageNum, Integer pageSize) {
        // 1.调用rpc查询
        PageBeanVo pageBeanVo = commentService.findCommentByPage(new ObjectId(publishId), 2, pageNum, pageSize);
        // 2.封装commentVo
        // 2-1 声明voList
        List<CommentVo> voList = new ArrayList<>();
        // 2-2 获取commentList
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        // 2-3 遍历
        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                // 创建vo
                CommentVo vo = new CommentVo();
                // 先userInfo
                UserInfo userInfo = userInfoService.findById(comment.getUserId());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                // 后comment
                vo.setId(comment.getId().toHexString());
                vo.setContent(comment.getContent());
                vo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated()))); // 2022-03-18 11:10

                // 添加到集合
                voList.add(vo);
            }
        }

        // 3.将voList设置到分页对象
        pageBeanVo.setItems(voList);

        // 4.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 发表评论
    public void movementComment(String publishId, String content) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.根据publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());// 评论时间
        comment.setPublishId(movement.getId());// 动态id
        comment.setCommentType(2); // 评论类型
        comment.setUserId(userId);// 操作人id
        comment.setPublishUserId(movement.getUserId());// 动态发布人id
        comment.setContent(content); // 评论内容
        // 4.调用rpc保存
        commentService.saveComment(comment);
    }
}
